#coding=utf-8
#auth:beck shen
#date:2017-11-09


from __future__ import absolute_import

from .pool import ConnectionPool
from pytw.tools import log

from datetime import datetime
from collections import namedtuple


class _TableRows(list):

    def first(self):
        if not self:
            return None
        return self[0]


class _SQLObject(object):

    """
    用于过滤条件
    """

    def __init__(self, model_class, sql, is_need_result = False, fields = None):
        self._model_class = model_class
        self._sql = sql
        self._is_need_result = is_need_result
        self._fields = fields

    def filter(self, **conditions):
        """
        条件过滤
        """
        self._sql = '{0}{1}'.format(self._sql, 
            self._model_class.condition_str(conditions))
        return self

    @classmethod
    def pack_result(cls, name, fields, result):
        """
        将数据库查询返回结果集打包为namedtuple对象
        """
        values = []
        obj = namedtuple(name, fields)
        for value in result:
            v = obj._make(value)
            values.append(v)
        return _TableRows(values)

    def execute(self):
        log.sql('execute===>:', self._sql)
        #需要返回结果
        if self._is_need_result:
            result = self._model_class.query(self._sql)
            values = self.__class__.pack_result(self._model_class.__table__, 
                self._fields, result)
            return values
        self._model_class.operation(self._sql)
        return _TableRows()

        
class BaseModel(object):

    """
    简单的orm实现
    """

    __sql__ = _SQLObject

    __date_format__ = "%Y-%m-%d %H:%M:%S"
    #表字段默认值
    __defaults__ = {}    
    #数据库连接池
    __pool__ = None
    #表名称
    __table__ = ''

    @classmethod
    def _format_value(cls, v):
        """
        格式化值
        """
        if isinstance(v, datetime):
            _v = b"'%s'"%(v.strftime(cls.__date_format__))
        elif isinstance(v, (int, float)):
            _v = b"%s"%(v)
        else:
            if isinstance(v, unicode):
                v = v.encode('utf-8', 'ignore')
            _v = b"'%s'"%(str(v).replace("'", "''")
            .replace('\\', '\\\\')) 
        return _v      

    @classmethod
    def kv_to_equal_list(cls, items):
        """
        将kv转换为k = v的list
        """ 
        kveq_list = []
        for k, v in items.items():
            _v = cls._format_value(v)
            kveq_list.append(("{0} = {1}".format(k, _v)))
        return kveq_list
            
    @classmethod
    def condition_str(cls, items):
        """
        生成condition的sql串
        """
        if not items:
            return ''
        kveq_list = cls.kv_to_equal_list(items)
        s = ' where %s'%(' and '.join(kveq_list))
        return s
        
    @classmethod
    def update_str(cls, items):
        """
        根据kv生成条件语句
        """
        if not items:
            return ''
        kveq_list = cls.kv_to_equal_list(items)
        s = ', '.join(kveq_list)
        return s

    @classmethod
    def select_str(cls, fields):
        """
        select中间字段查询
        """
        if not fields:
            return ''
        s = ', '.join(fields)
        return s

    @classmethod
    def insert_str(cls, items):
        """
        kv装换为insert
        """
        k_list = [] 
        v_list = []
        for k, v in items.items():
            k_list.append(k)
            v_list.append(cls._format_value(v))
        #默认值
        for k, v in cls.__defaults__.items():
            if k not in items:
                k_list.append(k)
                if callable(v):
                    v = v()
                v_list.append(cls._format_value(v))
        ks = ', '.join(k_list)
        vs = ', '.join(v_list)
        return ks, vs

    @classmethod
    def query(cls, *args, **kwargs):
        return cls.__pool__.query(*args, **kwargs)

    @classmethod
    def operation(cls, *args, **kwargs):
        return cls.__pool__.operation(*args, **kwargs)

    @classmethod
    def select(cls, *fields):
        """
        查询,fields为字符串list
        """
        assert '*' not in fields
        select_str = cls.select_str(fields)
        s = 'select %s from %s'%(select_str, cls.__table__)
        sql = cls.__sql__(cls, s, is_need_result = True, fields = fields)
        return sql

    @classmethod
    def update(cls, **kv):
        """
        更改表
        """
        update_str = cls.update_str(kv)
        s = 'update %s set %s'%(cls.__table__, update_str) 
        sql = cls.__sql__(cls, s)
        return sql      

    @classmethod
    def insert(cls, **kv):
        """
        插入
        """
        ks, vs = cls.insert_str(kv)
        s = 'insert into %s(%s) values(%s)'%(cls.__table__, ks, vs)
        sql = cls.__sql__(cls, s)
        return sql

    @classmethod
    def delete(cls):
        """
        删除
        """
        s = 'delete from %s'%(cls.__table__) 
        sql = cls.__sql__(cls, s)
        return sql
